(function () {
    "use strict";
    
    var counters, ns, delay, elts;

    counters = [
        { prop: "type", desc: "test type" },
        { prop: "n", desc: "number of elements" },
        { prop: "insertion", desc: "insertion of elements" },
        { prop: "deletion", desc: "deletion of elements" },
        { prop: "append", desc: "append at end" },
        { prop: "prepend", desc: "insert at begin" }
    ];

    delay = 30;

    ns = [ 20, 200, 2000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000 ];

    (function () {
        var i, n;
        n = Math.max.apply(null, ns);
        elts = new Array(n);
        for (i = 0; i < n; ++i) {
            elts[i] = document.createElement('div');
            elts[i].appendChild(document.createTextNode(String(i)));
        }
    })();

    function gen_test(n) {
        var ret, i, body, next, start;

        body = document.querySelector("#playground");

        ret = {
            type: "gen",
            n: n
        };

        start = Date.now();
        for (i = 0, next = null; i < n; ++i) {
            body.insertBefore(elts[i], next);
            next = elts[i];
        }
        ret.prepend = Date.now() - start;        

        while (body.lastChild) {
            body.removeChild(body.lastChild);
        }
        
        start = Date.now();
        for (i = 0; i < n; ++i) {
            body.appendChild(elts[i]);
        }
        ret.append = Date.now() - start;        

        start = Date.now();
        while (body.lastChild) {
            body.removeChild(body.lastChild);
        }
        ret.deletion = Date.now() - start; 

        return ret;
    }

    function test(n) {
        var ret, i, start, next, odd, body;

        ret = {
            type: "ll",
            n: n
        };

        body = document.querySelector("#playground");

        start = Date.now();
        next = null;
        odd = false;
        for (i = 0; i < n; ++i, odd = !odd) {
            body.insertBefore(elts[i], next);
            if (odd) {
                next = elts[i];
            }
        }
        ret.insertion = Date.now() - start;

        start = Date.now();
        while (body.lastChild) {
            body.removeChild(body.lastChild);
        }
        ret.deletion = Date.now() - start;

        return ret;
    }

    function test_idx(n) {
        var ret, i, start, duration, body;

        ret = {
            type: "idx",
            n: n
        };

        body = document.querySelector("#playground");

        start = Date.now();
        for (i = 0; i < n; ++i) {
            body.insertBefore(elts[i], body.childNodes.item((i+1)>>>1));
        }
        ret.insertion = Date.now() - start;

        start = Date.now();
        while (body.lastChild) {
            body.removeChild(body.lastChild);
        }
        ret.deletion = Date.now() - start;
        
        return ret;
    }

    function eltWithText(type, txt) {
        var e;
        e = document.createElement(type);
        e.appendChild(document.createTextNode(txt));
        return e;
    }

    function addLine(line) {
        document.body.appendChild(eltWithText('div', line));
    }
    
    (function () {
        var table, head, i;

        function addRow(r) {
            var row;

            row = document.createElement('tr');

            counters.forEach(function (c) { 
                row.appendChild(eltWithText('td', r.hasOwnProperty(c.prop) ? String(r[c.prop]) : ""));
            });

            table.appendChild(row);
        }

        table = document.querySelector("#results");
        head = table.querySelector("tr.head");
        counters.forEach(function (c) { 
            head.appendChild(eltWithText('th', c.prop));
        });

        i = 0;
        function oneTestGen() {
            addRow(gen_test(ns[i]));
            setTimeout(oneTest, delay);
        }
        function oneTest() {
            addRow(test(ns[i]));
            setTimeout(oneTestIdx, delay);
        }
        function oneTestIdx() {
            addRow(test_idx(ns[i]));
            ++i;
            if (i < ns.length) {
                setTimeout(oneTestGen, delay);
            } else {
                document.querySelector("#end").style.display = "";
            }
        }
        setTimeout(oneTestGen, delay);
    }());
    //test(20);
    //test_idx(20);
    //test(2000);
    //test_idx(2000);
      //test(50000);
    //test_idx(50000);
}());
